十、移植u

您所在的位置:网站首页 uboot代码中调用烧写spinand flash 十、移植u

十、移植u

2024-06-23 04:55| 来源: 网络整理| 查看: 265

10. u-boot-2016.03移植之修改源码烧写JFFS2、烧写YAFFS与制作补丁

    前面我们通过修改uboot的代码让它支持串口、nand flash,nor flash,网络下载文件等功能,现在我们来实现最后一个功能,实现Uboot烧写YAFFS文件系统,同时制作uboot补丁方便以后的移植,避免重复造轮子。

10.1 烧写JFFS2文件系统

该uboot已经支持JFFS2文件系统的烧写了,我们先来烧写JFFS2文件系统,命令如下:

nfs 30000000 192.168.0.103:/home/book/works/first_fs/fs_mini_mdev.jffs2 //使用nfs下载fs_mini.jffs2文件系统到30000000地址 nand erase.part rootfs //擦除rootfs分区 nand write.jffs2 30000000 rootfs $filesize //使用nand write.jffs2将30000000地址的大小为filesize的文件写到rootfs分区

烧写完后,需要先设置文件系统的类型,在uboot中输入命令:

setenv bootargs console=ttySAC0 root=/dev/mtdblock3 rootfstype=jffs2

然后下载uImage:

nfs 32000000 192.168.0.103:/home/book/works/first_fs/uImage_4.3 //该uImage_4.3是Jz2440开发板资料提供的映像文件

然后输入以下命令,启动linux内核:

bootm 32000000

从下图的打印信息可知,linux成功挂载了JFFS2文件系统,启动成功。 在这里插入图片描述

10.2 修改代码支持YAFFS文件系统烧写

当前uboot不支持烧写YAFFS文件系统,可以验证一下,在uboot下执行以下命令:

nfs 30000000 192.168.0.102:/home/book/works/first_fs/fs_mini_mdev.yaffs2 nand erase.part rootfs nand write.yaffs 30000000 rootfs $filesize

打印信息如下: 在这里插入图片描述 上图显示:Unknown nand command suffix '.yaffs'.,说明此时的uboot还没有支持yaffs文件系统是烧写。 在uboot源码目录中搜索:Unknown nand command suffix,定位到cmd/nand.c 的do_nand函数,发现在do_nand函数里,有nand read或write的代码,而其中有对jffs2的支持,却并没有对yaffs2的支持。我们可以参考老版本的uboot(例如u-boot-2012.04.01的),在do_nand函数里的nand write/read部分加上一段代码,如下:

#ifdef CONFIG_CMD_NAND_TRIMFFS } else if (!strcmp(s, ".trimffs")) { if (read) { printf("Unknown nand command suffix '%s'\n", s); return 1; } ret = nand_write_skip_bad(nand, off, &rwsize, NULL, maxsize, (u_char *)addr, WITH_DROP_FFS | WITH_WR_VERIFY); #endif /*上面是原代码,在这里添加如下代码*/ #ifdef CONFIG_CMD_NAND_YAFFS } else if (!strcmp(s, ".yaffs")) { if (read) { printf("Unknown nand command suffix ‘%s‘.\n", s); return 1; } ret = nand_write_skip_bad(nand, off, &rwsize,NULL,//这里参数和老版比要修改下 maxsize,(u_char *)addr, WITH_YAFFS_OOB); #endif

在nand_help_text[]里添加nand write.yaffs的帮助信息:(在cmd/nand.c)

#ifdef CONFIG_CMD_NAND_YAFFS "nand write.yaffs - addr off|partition size\n" " write ‘size‘ bytes starting at offset ‘off‘ with yaffs format\n" " from memory address ‘addr‘, skipping bad blocks.\n" #endif

修改nand_write_skip_bad函数,该函数代码如下:(该函数在drivers/mtd/nand/nand_util.c)

int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, size_t *actual, loff_t lim, u_char *buffer, int flags) { int rval = 0, blocksize; size_t left_to_write = *length; size_t used_for_write = 0; u_char *p_buffer = buffer; int need_skip; if (actual) *actual = 0; /*以下是添加*/ #ifdef CONFIG_CMD_NAND_YAFFS if (flags & WITH_YAFFS_OOB) { if (flags & ~WITH_YAFFS_OOB) return -EINVAL; int pages; pages = nand->erasesize / nand->writesize; blocksize = (pages * nand->oobsize) + nand->erasesize; if (*length % (nand->writesize + nand->oobsize)) { printf ("Attempt to write incomplete page" " in yaffs mode\n"); return -EINVAL; } } else #endif /*以上是添加*/ { blocksize = nand->erasesize; } /* * nand_write() handles unaligned, partial page writes. * * We allow length to be unaligned, for convenience in * using the $filesize variable. * * However, starting at an unaligned offset makes the * semantics of bad block skipping ambiguous (really, * you should only start a block skipping access at a * partition boundary). So don't try to handle that. */ if ((offset & (nand->writesize - 1)) != 0) { printf("Attempt to write non page-aligned data\n"); *length = 0; return -EINVAL; } need_skip = check_skip_len(nand, offset, *length, &used_for_write); if (actual) *actual = used_for_write; if (need_skip lim) { puts("Size of write exceeds partition or device limit\n"); *length = 0; return -EFBIG; } if (!need_skip && !(flags & WITH_DROP_FFS)) { rval = nand_write(nand, offset, length, buffer); if ((flags & WITH_WR_VERIFY) && !rval) rval = nand_verify(nand, offset, *length, buffer); if (rval == 0) return 0; *length = 0; printf("NAND write to offset %llx failed %d\n", offset, rval); return rval; } while (left_to_write > 0) { size_t block_offset = offset & (nand->erasesize - 1); size_t write_size, truncated_write_size; WATCHDOG_RESET(); if (nand_block_isbad(nand, offset & ~(nand->erasesize - 1))) { printf("Skip bad block 0x%08llx\n", offset & ~(nand->erasesize - 1)); offset += nand->erasesize - block_offset; continue; } if (left_to_write writesize; size_t pagesize_oob = pagesize + nand->oobsize; struct mtd_oob_ops ops; ops.len = pagesize; ops.ooblen = nand->oobsize; ops.mode = MTD_OPS_RAW; //这里要改为RAW ops.ooboffs = 0; pages = write_size / pagesize_oob; for (page = 0; page _write_oob(nand, offset, &ops); if (rval != 0) break; offset += pagesize; p_buffer += pagesize_oob; } } else #endif /*以上是添加*/ { /*这里要添加左大括号*/ truncated_write_size = write_size; #ifdef CONFIG_CMD_NAND_TRIMFFS if (flags & WITH_DROP_FFS) truncated_write_size = drop_ffs(nand, p_buffer, &write_size); #endif rval = nand_write(nand, offset, &truncated_write_size, p_buffer); if ((flags & WITH_WR_VERIFY) && !rval) rval = nand_verify(nand, offset, truncated_write_size, p_buffer); offset += write_size; p_buffer += write_size; } /*这里要添加右大括号*/ if (rval != 0) { printf("NAND write to offset %llx failed %d\n", offset, rval); *length -= left_to_write; return rval; } left_to_write -= write_size; } return 0; } 10.3 测试

修改好代码后,重新编译uboot,烧写到开发板NOR Flash,重新启动输入以下命令:

nfs 30000000 192.168.0.102:/home/book/works/first_fs/fs_mini_mdev.yaffs2 nand erase.part rootfs nand write.yaffs 30000000 rootfs $filesize //烧写文件系统 setenv bootargs console=ttySAC0 root=/dev/mtdblock3 rootfstype=yaffs nfs 32000000 192.168.0.102:/home/book/works/first_fs/uImage_4.3 //该uImage_4.3是Jz2440开发板资料提供的映像文件 bootm 32000000

打印信息如下: 在这里插入图片描述 从下图的打印信息可知,linux成功挂载了YAFFS2文件系统,启动成功。 在这里插入图片描述

10.4 制作补丁

在uboot根目录执行如下命令:

make distclean (清除之前编译生成的所有文件) rm u-boot.dis cd .. mv u-boot-2016.03 u-boot-2016.03_jz2440 (重命名) tar xjf u-boot-2016.03.tar.bz2 (解压得到源码) diff -urN u-boot-2016.03 u-boot-2016.03_jz2440 > u-boot-2016.03_jz2440.patch (这就是补丁文件名)

打补丁命令:

cd u-boot-2016.03 patch -p1


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3